package com.automapper.sqlbuilder;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.persistence.Table;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.automapper.constants.ParameterConstants;
import com.automapper.exception.AutoMapperException;
import com.automapper.sharding.TableSharding;
import com.automapper.utils.PropertiesFacade;

public abstract class SqlBuilderTemplate {
	private static final Logger log = LoggerFactory.getLogger(SqlBuilderTemplate.class);
	
	public abstract String buildSql(Object parameterObject, PropertiesFacade propertiesFacade) throws Exception ;
		
	protected void filter(Map<String, Object> paramMap, List<String> columns) {
		List<String> excludeCol = getExcludeColumn(paramMap);
		columns.removeAll(excludeCol);
	}
	
	protected String getTableName(Map<String, Object> parameterMap) {	
		String tableName = null;
		if (parameterMap.containsKey(ParameterConstants.TABLE_NAME) && parameterMap.get(ParameterConstants.TABLE_NAME) != null) {
			tableName = parameterMap.get(ParameterConstants.TABLE_NAME).toString();
		}
		
		if (StringUtils.isBlank(tableName)) {
			Object tmpParameter = null;
			Object parameter = parameterMap.get(ParameterConstants.PARAM);
			int size = 0;
			if (parameter instanceof List) {
				List<Object> list = (List<Object>) parameter;
				size = list.size();
				tmpParameter = list.get(0);
			} else {
				tmpParameter = parameter;
			}
			
			if (tmpParameter instanceof TableSharding) {
				if (size > 1) {
					log.warn("集合不能使用分表策略");
				} else {
					TableSharding sharding = (TableSharding) tmpParameter;
					tableName = sharding.getShardingTable();
				}
			}
			
			if (StringUtils.isBlank(tableName)) {
				Table table = tmpParameter.getClass().getAnnotation(Table.class);
				AutoMapperException.NullRuntimeException(table, "对象没有定义注解@Table");
				tableName = table.name();
			}
		}
		
		AutoMapperException.StringisBlankRuntimeException(tableName, "你确定你不是在逗我吗，表名都没有");
		return tableName;
	}
	
	protected List<String> getExcludeColumn(Map<String, Object> paramMap) {
		if (!paramMap.containsKey(ParameterConstants.EXCLUDE_COLUMN)) {
			return new ArrayList<>();
		} else {
			return (List<String>) paramMap.get(ParameterConstants.EXCLUDE_COLUMN);
		}
	}
}
